package parser

import (
	"bufio"
	"bytes"
	"errors"
	"io"
	"strconv"
	"strings"
)

type Payload struct {
	Data redis.Reply
	Err error
}

//ParseStream reads data from io.Reader and send payloads throuth channel
func ParseStream(reader io.Reader) <- chan *Payload {
	ch := make(chan *Payload)
	go parse0(reader,ch)
	return ch
}

type readState struct {
	readingMultiLine bool
	expectedArgsCount int
	msgType 	byte
	args 		[][]byte
	bulkLen 	int64
}

func (s *readState) finished() bool {
	return s.expectedArgsCount > 0 && len(s.args) == s.expectedArgsCount
}

func parse0(reader io.Reader, ch chan<- *Payload) {
	defer func() {
		if err := recover(); err != nil {
			logger.Error(string(debug.Stack()))
		}
	}()

	bufReader := bufio.NewReader(reader)
	var state readState
	var err error
	var msg []byte
	for {
		// read line
		var ioErr bool
		msg,ioErr,err = readLine(bufReader,&state)
		if err != nil {
			if ioErr {
				ch <- &Payload{
					Err:err,
				}
				close(ch)
				return
			}
			// protocol err, reset read state
			ch <- &Payload{
				Err:err,
			}
			state = readState{}
			continue
		}
		// parse line
		if !state.readingMultiLine {
			
		}
	}
}

func readLine(bufReader *bufio.Reader, state *readState) {
	var msg []byte
	var err error
	if state.bulkLen == 0 { // read normal line
		msg,err = bufReader.ReadBytes('\n')
		if err != nil {
			return nil,true, err
		}
		if len(msg) == 0 || msg[len(msg) - 2] != '\r' {
			return nil, false, errors.New("protocol error:" + string(msg))
		}
	} else { // read bulk line (binary safe)
		msg := make([]byte,state.bulkLen + 2)
		_,err = io.ReadFull(bufReader,msg)
		if err != nil {
			return nil,true,err
		}
		if len(msg) == 0 ||
			msg[len(msg) -2] != '\r' ||
			msg[len(msg) -1] != '\n' {
				return nil, false, errors.New("protocol error:" + string(msg))
		}
		state.bulkLen = 0
	}
	return msg,false,nil
}

